package com.quanyan.orderpay.service.check.account.impl;

import com.quanyan.orderpay.service.check.account.SaveAccountWaterService;
import com.quanyan.orderpay.service.check.account.WaterMessageDecoder;
import com.quanyan.orderpay.service.check.account.WaterMessageDecoderFactory;
import com.quanyan.pay.api.alipay.service.AlipayAPIService;
import com.quanyan.pay.api.alipay.vo.AliBillDataItem;
import com.quanyan.pay.api.alipay.vo.AliBillDataRespVo;
import com.quanyan.pay.api.alipay.vo.AliDataDataserviceBillDownloadurlQueryReqVo;
import com.quanyan.pay.api.chinaums.service.ChinaumsAPIService;
import com.quanyan.pay.api.chinaums.vo.UmBillDataItem;
import com.quanyan.pay.api.chinaums.vo.UmBillDataRespVo;
import com.quanyan.pay.api.wechat.service.impl.WechatAPIServiceImpl;
import com.quanyan.pay.api.wechat.vo.WxDownloadBillReqVo;
import com.quanyan.pay.api.wechat.vo.WxDownloadBillRespVo;
import com.quanyan.pay.entity.AccountPayWater;
import com.quanyan.pay.entity.AlipayAccount;
import com.quanyan.pay.entity.AlipayConfigAccount;
import com.quanyan.pay.entity.WeichatAccount;
import com.quanyan.pay.enums.AliBillTypeEnum;
import com.quanyan.pay.enums.WxBillTypeEnum;
import com.quanyan.pay.enums.WxReturnCodeEnum;
import com.quanyan.pay.mapper.AccountPayWaterMapper;
import com.quanyan.pay.service.AccountService;
import com.quanyan.pay.vo.response.PayAccount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by pp.zuo on 2017/3/29.
 */
@Service("saveWechatAccountWaterService")
public class SaveAccountWaterServiceImpl implements SaveAccountWaterService {

    private Logger logger = LoggerFactory.getLogger(SaveAccountWaterServiceImpl.class);


    @Autowired
    private AccountService accountService;

    @Autowired
    private AlipayAPIService alipayAPIService;

    @Autowired
    private ChinaumsAPIService chinaumsAPIService;

    @Autowired
    private AccountPayWaterMapper accountPayWaterMapper;



    @Override
    public void saveYesterdayAllAccountWater() {
        saveYesterdayWechatAccountWater();
        saveYesterdayAlipayAccountWater();
    }

    @Override
    public void saveYesterdayWechatAccountWater() {
        Date date = getYesterday();
        DateFormat wechatDateFormat = new SimpleDateFormat("yyyyMMdd");
        String wechatDateStr = wechatDateFormat.format(date);

        saveWechatAccountWater(wechatDateStr);
    }

    @Override
    public void saveYesterdayAlipayAccountWater() {
        Date date = getYesterday();

        DateFormat alipayDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String alipayDateStr = alipayDateFormat.format(date);
        saveAlipayAccountWater(alipayDateStr);
    }

    @Override
    public void saveYesterdayChinaumsAccountWater() {
        saveChinaumsAccountWater("");
    }

    @Override
    public void saveWechatAccountWater(String dateStr) {
        saveWechatSuccessWater(dateStr);
        saveWechatRefundWater(dateStr);
    }

    private Date getYesterday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        return cal.getTime();
    }

    private List<String[]> getWechatAccountWater(WxBillTypeEnum type, String date) {
        List<String[]> resultList = new ArrayList<>();

        WxDownloadBillReqVo vo = new WxDownloadBillReqVo();
        vo.setBill_date(date);
        vo.setBill_type(type);

        PayAccount payAccount = accountService.selectAllAccount();
        List<WeichatAccount> wxAccountList = payAccount.getWxAccountList();
        for (WeichatAccount weichatAccount : wxAccountList) {
            vo.setAppid(weichatAccount.getAppId());
            vo.setMch_id(weichatAccount.getMchId());
            vo.setApiKey(weichatAccount.getWxKey());

            WechatAPIServiceImpl wechatAPIService = new WechatAPIServiceImpl();
            WxDownloadBillRespVo respVo = wechatAPIService.downloadBill(vo);
            if (respVo.isRet() && respVo.getReturn_code() == WxReturnCodeEnum.SUCCESS) {
                resultList.addAll(respVo.getData());
            }
        }

        return resultList;
    }

    private void saveWechatRefundWater(String dateStr) {
        List<String[]> dataList = getWechatAccountWater(WxBillTypeEnum.REFUND, dateStr);

        if (dataList == null) {
            return;
        }

        WaterMessageDecoder waterMessageDecoder
                = WaterMessageDecoderFactory.getDecoderByType(WaterMessageDecoderFactory.DecoderType.WECHAT_REFUND);
        int inserted = 0;
        for (String[] data : dataList) {
            AccountPayWater accountPayWater = waterMessageDecoder.decode(data);
            inserted += accountPayWaterMapper.insertSelective(accountPayWater);
        }

        if (inserted > 0) {
            logger.info("【微信退款】-第三方支付流水成功保存了{}条数据", inserted);
        } else {
            logger.info("【微信退款】-无数据插入");
        }
    }

    private void saveWechatSuccessWater(String dateStr) {
        List<String[]> dataList = getWechatAccountWater(WxBillTypeEnum.SUCCESS, dateStr);

        WaterMessageDecoder waterMessageDecoder
                = WaterMessageDecoderFactory.getDecoderByType(WaterMessageDecoderFactory.DecoderType.WECHAT_SUCCESS);
        int inserted = 0;
        for (String[] data : dataList) {
            AccountPayWater accountPayWater = waterMessageDecoder.decode(data);
            inserted += accountPayWaterMapper.insertSelective(accountPayWater);
        }

        if (inserted > 0) {
            logger.info("【微信支付】-第三方支付流水成功保存了{}条数据", inserted);
        } else {
            logger.info("【微信支付】-无数据插入");
        }
    }


    @Override
    public void saveAlipayAccountWater(String dateStr) {
        AlipayConfigAccount alipayConfigAccount = new AlipayConfigAccount();

        PayAccount payAccount = accountService.selectAllAccount();
        List<AlipayAccount> alipayAccountList = payAccount.getAlipayAccountList();

        AliDataDataserviceBillDownloadurlQueryReqVo vo = new AliDataDataserviceBillDownloadurlQueryReqVo(alipayConfigAccount);
        vo.setBill_date(dateStr);
        vo.setBill_type(AliBillTypeEnum.trade);

        int inserted = 0;
        for (AlipayAccount alipayAccount : alipayAccountList) {
            alipayConfigAccount.setAppId(alipayAccount.getAppId());
            alipayConfigAccount.setAlipayPublicKey(alipayAccount.getOpenPublicKey());
            alipayConfigAccount.setAppPrivateKey(alipayAccount.getPrivateKey());

            AliBillDataRespVo response = alipayAPIService.downloadAndProcessBillData(vo);

            WaterMessageDecoder waterMessageDecoder
                    = WaterMessageDecoderFactory.getDecoderByType(WaterMessageDecoderFactory.DecoderType.ALIPAY_ALL);
            for (AliBillDataItem aliBillDataItem : response.getBillData()) {
                AccountPayWater accountPayWater = waterMessageDecoder.decode(aliBillDataItem);
                if (accountPayWater == null) {
                    continue;
                }
                accountPayWater.setSellerId(alipayAccount.getPartner());
                inserted += accountPayWaterMapper.insertSelective(accountPayWater);
            }
        }


        if (inserted > 0) {
            logger.info("【支付宝】-第三方支付流水成功保存了{}条数据", inserted);
        } else {
            logger.info("【支付宝】-无数据插入");
        }
    }

    private void saveChinaumsAccountWater(String dateStr) {
        String hostName = "192.168.30.64";
        String userName = "orderpay_ftpuser";
        String password = "64P5WaQdSLXL";
        String sampleFileName = "对账单参考格式.xls";

        UmBillDataRespVo respVo = chinaumsAPIService.processBillData(hostName, userName, password, sampleFileName);
        WaterMessageDecoder waterMessageDecoder
                = WaterMessageDecoderFactory.getDecoderByType(WaterMessageDecoderFactory.DecoderType.CHINA_UMS);
        int inserted = 0;

        List<UmBillDataItem> list = respVo.getBillData();

        for (UmBillDataItem billItem : list) {
            AccountPayWater accountPayWater = waterMessageDecoder.decode(billItem);
            inserted += accountPayWaterMapper.insertSelective(accountPayWater);
        }

        if (inserted > 0) {
            logger.info("【银联支付】-第三方支付流水成功保存了{}条数据", inserted);
        } else {
            logger.info("【银联支付】-无数据插入");
        }
    }
}
